

package Bayreuth;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Objects;
import java.util.Random;
import java.util.Set;
import java.util.concurrent.ThreadLocalRandom;

import javax.swing.JOptionPane;





public class PrefAgg
{
   static final String[] Options={"1","2","3","12","13","23","123"}; //possible options for each level of the ranking

 //---------------------------------------------Distance Matrixes for KS, DP and CS--------------------------------

   static final int[][] DPDistanceMatrix= new int[][] {{0,1,1,1,1,1,1,2,2,2,2,2,2},{1,0,2,2,2,2,2,1,2,1,2,3,3},{1,2,0,2,2,2,2,3,1,3,3,1,3},
   {1,2,2,0,2,2,2,3,3,3,1,3,1},{1,2,2,2,0,2,2,1,1,3,3,3,3},{1,2,2,2,2,0,2,3,3,1,1,3,3},
   {1,2,2,2,2,2,0,3,3,3,3,1,1},{2,1,3,3,1,3,3,0,2,2,4,4,4},{2,2,1,3,1,3,3,2,0,4,4,2,4},
   {2,1,3,3,3,1,3,2,4,0,2,4,4},{2,2,3,1,3,1,3,4,4,2,0,4,2},{2,3,1,3,3,3,1,4,2,4,4,0,2},
   {2,3,3,1,3,3,1,4,4,4,2,2,0}};
		   
    static final int[][] CSDistanceMatrix= new int[][] {{0,2,2,2,2,2,2,3,3,3,3,3,3},{2,0,3,3,2,2,4,1,3,1,3,4,4},
  {2,3,0,3,2,4,2,3,1,4,4,1,3},{2,3,3,0,4,2,2,4,4,3,1,3,1},{2,2,2,4,0,3,3,1,1,3,4,3,4},{2,2,4,2,3,0,3,3,4,1,1,4,3},
  {2,4,2,2,3,3,0,4,3,4,3,1,1},{3,1,3,4,1,3,4,0,2,2,4,4,4},{3,3,1,4,1,4,3,2,0,4,4,2,4},{3,1,4,3,3,1,4,2,4,0,2,3,4},
  {3,3,4,1,4,1,3,4,4,2,0,4,2},{3,4,1,3,3,4,1,4,2,3,4,0,2},{3,4,3,1,4,3,1,4,4,4,2,2,0}};

    static final int[][] KDistanceMatrix= new int[][] {{0,2,2,2,2,2,2,3,3,3,3,3,3},{2,0,4,4,2,2,4,1,3,1,3,5,5},
    {2,4,0,4,2,4,2,3,1,5,5,1,3},{2,4,4,0,4,2,2,5,5,3,1,1,1},{2,2,2,4,0,4,4,1,1,3,5,3,5},{2,2,4,2,4,0,4,3,5,1,1,5,3},
{2,4,2,2,4,4,0,5,3,5,3,1,1},{3,1,3,5,1,3,5,0,2,2,4,4,6},{3,3,1,5,1,5,3,2,0,4,6,2,4},{3,1,5,3,3,1,5,2,4,0,2,6,4},
   {3,3,5,1,5,1,3,4,6,2,0,4,2},{3,5,1,1,3,5,1,4,2,6,4,0,2},{3,5,3,1,5,3,1,6,4,4,2,2,0}};

 //------------------------------------------------------------------------------------------------------------------------

   static List<String>[] Rankings;        //list of rankings
   static List<String>[] StrictRankings;        //list of strict rankings

   double[] initialRel;                   //reliabilities agents assign to themselves
   double[] initialRel2;                  //reliabilities agents assign to others. assume this to be the same for all others
   int[] initialVotes;
   double[][][] EachRoundReliabilities;   //to be used when reliabilities will change from each round to next
   Random r=new Random();                 //random generator
   //double randomThreshold[];
   public int numAgents;  //group size
   int numDelibRounds; //number of deliberation rounds



//----------------------------------------------------initializing--------------------------------------------------------------------

public PrefAgg(int numAgents, double rel1, double rel2, int numDelibRounds)
{
this.Rankings=new List[13];
this.StrictRankings=new List[6];

this.numAgents=numAgents;
this.numDelibRounds=numDelibRounds;
this.EachRoundReliabilities=new double[numDelibRounds][numAgents][numAgents];
this.initialRel= new double[this.numAgents];
this.initialRel2= new double[this.numAgents];

for(int i=0; i< this.numAgents;i++)
{
this.initialRel[i]=rel1;  //setting rel1 to be the reliability that agents assign to themselves-same for everyone
this.initialRel2[i]=rel2; //setting rel1 to be the reliability that agents assign to others-same for everyone
}

//-------------------------------13 possible rankings of three alternatives--------------------------------
List<String> l1= new ArrayList<String>();
List<String> l2= new ArrayList<String>();
List<String> l3= new ArrayList<String>();
List<String> l4= new ArrayList<String>();
List<String> l5= new ArrayList<String>();
List<String> l6= new ArrayList<String>();
List<String> l7= new ArrayList<String>();
List<String> l8= new ArrayList<String>();
List<String> l9= new ArrayList<String>();
List<String> l10= new ArrayList<String>();
List<String> l11= new ArrayList<String>();
List<String> l12= new ArrayList<String>();
List<String> l13= new ArrayList<String>();

l1.add(Options[0]);
l1.add(Options[1]);
l1.add(Options[2]);

l2.add(Options[0]);
l2.add(Options[2]);
l2.add(Options[1]);

l3.add(Options[1]);
l3.add(Options[0]);
l3.add(Options[2]);

l4.add(Options[1]);
l4.add(Options[2]);
l4.add(Options[0]);

l5.add(Options[2]);
l5.add(Options[0]);
l5.add(Options[1]);

l6.add(Options[2]);
l6.add(Options[1]);
l6.add(Options[0]);

l7.add(Options[0]);
l7.add(Options[5]);

l8.add(Options[1]);
l8.add(Options[4]);

l9.add(Options[2]);
l9.add(Options[3]);

l10.add(Options[3]);
l10.add(Options[2]);

l11.add(Options[4]);
l11.add(Options[1]);

l12.add(Options[5]);
l12.add(Options[0]);

l13.add(Options[6]);


//--------fixing the order of possible rankings generated above based on which the distance matrixes are calculated ---------------------------------



PrefAgg.Rankings[0]= l13;
PrefAgg.Rankings[1]= l10;
PrefAgg.Rankings[2]= l11;
PrefAgg.Rankings[3]= l12;
PrefAgg.Rankings[4]= l7;
PrefAgg.Rankings[5]= l8;
PrefAgg.Rankings[6]= l9;
PrefAgg.Rankings[7]= l1;
PrefAgg.Rankings[8]= l2;
PrefAgg.Rankings[9]= l3;
PrefAgg.Rankings[10]= l4;
PrefAgg.Rankings[11]= l5;
PrefAgg.Rankings[12]= l6;



PrefAgg.StrictRankings[0]= l1;
PrefAgg.StrictRankings[1]= l2;
PrefAgg.StrictRankings[2]= l3;
PrefAgg.StrictRankings[3]= l4;
PrefAgg.StrictRankings[4]= l5;
PrefAgg.StrictRankings[5]= l6;

}

//-------------given a ranking "l" and an alternative "input" returns the rank of the alternative in l----------------------------------------------------------------------------------------


public int IndexOf(int input, List<String> l)
{
	int index=1110; // a random initial value used later for error check
	List<String> givenList=l; // the given ranking
	int toBeChecked=input; // the given alternative
	int length= l.size();
	for(int i=0; i< length; i++)
	{
		int k=0;
		k=givenList.get(i).length();
		String[] eachLevel= new String[k];
		eachLevel=givenList.get(i).split("");
		for(int z=0; z< k; z++)
		{
			if(Objects.equals(eachLevel[z],String.valueOf(toBeChecked)))
			{
				index=i;
				break;
			}
		}
	}
	if(index==1110) System.out.println("error"); //for error checking
	return index+1;
}
//----------------------------------------------voting randomly-------------------------------------------------------
public int[] voting()
{
	int[] Votes=new int[this.numAgents];
	
	for(int i=0; i< this.numAgents;i++)
	{
		int randomNum = ThreadLocalRandom.current().nextInt(0, 13); //assigns to each agent a number between 0 and 12 representing the agents chosen ranking
		Votes[i]=randomNum;
	}	
	return Votes;
}

//----------------------------------------------strict voting randomly-------------------------------------------------------
public int[] Stvoting()
{
	int[] StVotes=new int[this.numAgents];
	
	for(int i=0; i< this.numAgents;i++)
	{
		int randomNum = ThreadLocalRandom.current().nextInt(0, 6); //assigns to each agent a number between 0 and 12 representing the agents chosen ranking
		StVotes[i]=randomNum+7;
	}
	return StVotes;
}


//-------------------------------------------------DP update----------------------------------------------------
//-----------Given two rankings vote1 and vote2 returns the ranking which minimizes the average DP distance to the vote1 and vote2 weighted by ther eliabilities

public int DPupdate(int vote1, int vote2, double rel1, double rel2)
{
	double[] DPAvDis= new double[13];     //to store average distances
	for(int i=0; i<13; i++)
	{
		DPAvDis[i]= Math.sqrt(rel1*java.lang.Math.pow(PrefAgg.DPDistanceMatrix[vote1][i],2)+rel2* java.lang.Math.pow(PrefAgg.DPDistanceMatrix[vote2][i],2));
	} //for each i sets the valueDPAvDis[i] to the average distance of the ranking number i to vote1 and vote2 weighted by the reliabilities	
	int counter= 0;
	for(int j=1; j<13; j++)     //finds the i with the minimal average distance to vote1 and vote2
	{
		if(DPAvDis[j]< DPAvDis[counter])
		{
			counter= j;
		}	
		if(DPAvDis[j]== DPAvDis[counter])
		{
			int randomNumber = ThreadLocalRandom.current().nextInt(0, 2);
			if(randomNumber==0)
			{
				counter= j;
			}
		}	
	}
	return counter;
}




//-------------------------------------------------DP Strict update----------------------------------------------------
//-----------Given two rankings vote1 and vote2 returns the ranking which minimizes the average DP distance to the vote1 and vote2 weighted by ther eliabilities

public int DPStupdate(int vote1, int vote2, double rel1, double rel2)
{
	double[] DPStAvDis= new double[6];     //to store average distances
	for(int i=0; i<6; i++)
	{
		DPStAvDis[i]= Math.sqrt(rel1*java.lang.Math.pow(PrefAgg.DPDistanceMatrix[vote1][i+7],2)+rel2* java.lang.Math.pow(PrefAgg.DPDistanceMatrix[vote2][i+7],2));	
	} //for each i sets the valueDPAvDis[i] to the average distance of the ranking number i to vote1 and vote2 weighted by the reliabilities	
	int counter= 0;
	for(int j=1; j<6; j++)     //finds the i with the minimal average distance to vote1 and vote2
	{
		if(DPStAvDis[j]< DPStAvDis[counter])
		{
			counter= j;
		}
		if(DPStAvDis[j]== DPStAvDis[counter])
		{
			int randomNumber = ThreadLocalRandom.current().nextInt(0, 2);
			if(randomNumber==0)
			{
				counter= j;
			}	
		}	
	}
	return counter+7;
}



//-------------------------------------------------KS update----------------------------------------------------
//-----------Given two rankings vote1 and vote2 returns the ranking which minimizes the average KS distance to the vote1 and vote2 weighted by ther eliabilities


public int KSupdate(int vote1, int vote2, double rel1, double rel2)
{
	double[] KSAvDis= new double[13]; //to store average distances
	for(int i=0; i<13; i++)
	{
		KSAvDis[i]= Math.sqrt(rel1*java.lang.Math.pow(PrefAgg.KDistanceMatrix[vote1][i],2)+rel2* java.lang.Math.pow(PrefAgg.KDistanceMatrix[vote2][i],2));
	} //for each i sets the value KSAvDis[i] to the average distance of the ranking number i to vote1 and vote2 weighted by the reliabilities	
	int counter= 0;
	for(int j=1; j<13; j++) //finds the i with the minimal average distance to vote1 and vote2
	{
		if(KSAvDis[j]< KSAvDis[counter])
		{
			counter= j;
		}
		if(KSAvDis[j]== KSAvDis[counter])
		{
			int randomNumber = ThreadLocalRandom.current().nextInt(0, 2);
			if(randomNumber==0)
			{
				counter= j;
			}
		}	
	}
	return counter;
}

//-------------------------------------------------KS Strict update---------------------------------------------------
//-----------Given two rankings vote1 and vote2 returns the ranking which minimizes the average KS distance to the vote1 and vote2 weighted by ther eliabilities


public int KSStupdate(int vote1, int vote2, double rel1, double rel2)
{
	double[] KSStAvDis= new double[6]; //to store average distances
	for(int i=0; i<6; i++)
	{
		KSStAvDis[i]= Math.sqrt(rel1*java.lang.Math.pow(PrefAgg.KDistanceMatrix[vote1][i+7],2)+rel2* java.lang.Math.pow(PrefAgg.KDistanceMatrix[vote2][i+7],2));
	} //for each i sets the value KSAvDis[i] to the average distance of the ranking number i to vote1 and vote2 weighted by the reliabilities	
	int counter= 0;
	for(int j=1; j<6; j++) //finds the i with the minimal average distance to vote1 and vote2
	{
		if(KSStAvDis[j]< KSStAvDis[counter])
		{
			counter= j;
		}
		if(KSStAvDis[j]== KSStAvDis[counter])
		{
			int randomNumber = ThreadLocalRandom.current().nextInt(0, 2);
			if(randomNumber==0)
			{
				counter= j;
			}
		}
	}
	return counter+7;
}

//-------------------------------------------------CS update----------------------------------------------------
//-----------Given two rankings vote1 and vote2 returns the ranking which minimizes the average CS distance to the vote1 and vote2 weighted by the reliabilities


public int CSupdate(int vote1, int vote2, double rel1, double rel2)
{
	double[] CSAvDis= new double[13]; //to store average distances
	for(int i=0; i<13; i++)
	{
		CSAvDis[i]= Math.sqrt(rel1*java.lang.Math.pow(PrefAgg.CSDistanceMatrix[vote1][i],2)+rel2* java.lang.Math.pow(PrefAgg.CSDistanceMatrix[vote2][i],2));
	} //for each i sets the value KSAvDis[i] to the average distance of the ranking number i to vote1 and vote2 weighted by the reliabilities
	int counter= 0;
	for(int j=1; j<13; j++) //finds the i with the minimal average distance to vote1 and vote
	{
		if(CSAvDis[j]< CSAvDis[counter])
		{
			counter= j;
		}
		if(CSAvDis[j]== CSAvDis[counter])
		{
			int randomNumber = ThreadLocalRandom.current().nextInt(0, 2);
			if(randomNumber==0)
			{
				counter= j;
			}
		}
	}
	return counter;
}


//-------------------------------------------------CS strict update----------------------------------------------------
//-----------Given two rankings vote1 and vote2 returns the ranking which minimizes the average CS distance to the vote1 and vote2 weighted by the reliabilities


public int CSStupdate(int vote1, int vote2, double rel1, double rel2)
{
	double[] CSStAvDis= new double[6]; //to store average distances
	for(int i=0; i<6; i++)
	{
		CSStAvDis[i]= Math.sqrt(rel1*java.lang.Math.pow(PrefAgg.CSDistanceMatrix[vote1][i+7],2)+rel2* java.lang.Math.pow(PrefAgg.CSDistanceMatrix[vote2][i+7],2));
	} //for each i sets the value KSAvDis[i] to the average distance of the ranking number i to vote1 and vote2 weighted by the reliabilities	
	int counter= 0;
	for(int j=1; j<6; j++) //finds the i with the minimal average distance to vote1 and vote
	{
		if(CSStAvDis[j]< CSStAvDis[counter])
		{
			counter= j;
		}
		if(CSStAvDis[j]== CSStAvDis[counter])
		{	
			int randomNumber = ThreadLocalRandom.current().nextInt(0, 2);
			if(randomNumber==0)
			{
				counter= j;
			}
		}	
	}
	return counter+7;
}

//-----------------------------------------------------Deliberation with DP distance------------------------------------------------

public int[] DelibDP(int[] votes) //takes as input a set of integers between 0-12 representing the agents chosen ranking
{
	int[][] DelibRoundsResults= new int[this.numDelibRounds+1][this.numAgents]; //resulting profiles at each round of deliberation
	int[][] eachRoundResults= new int[this.numAgents+1][this.numAgents]; //resulting profiles at each step of a round of deliberation
	double[][] LastEffectiveReliabilities= new double[this.numAgents][this.numAgents];//reliabilities assigned to agents by other agents
	for(int k=0; k< this.numAgents; k++)
	{
		DelibRoundsResults[0][k]= votes[k]; //initial profile (round zero)
	}
	for(int i=1; i<numDelibRounds+1; i++)  //calculating results at each round
	{	
		int[] LastRoundResults=new int[this.numAgents];
		for(int w=0; w< this.numAgents; w++) //taking the results of last round
		{			
			LastRoundResults[w]=DelibRoundsResults[i-1][w];
		}	
		for(int k=0; k< this.numAgents; k++)
		{
			this.EachRoundReliabilities[i-1][k][k]=this.initialRel[k]; //assigning initial self reliabilities
		}
		for(int s=0; s<this.numAgents; s++ )
		{
			for(int w=0; w < this.numAgents; w++)
			{
				if(w!=s)
				{
					this.EachRoundReliabilities[i-1][s][w]= initialRel2[s];
					//assigning reliabilities by the agent w to other agents. all agents assign same reliabilities to every other agent in every round -- to change if assigning different estimated reliabilities in each round
				}
			}
		}
		LastEffectiveReliabilities=EachRoundReliabilities[i-1];	 //reliabilities to be used-- currently remain the same in all rounds
		for(int j=0; j< this.numAgents+1; j++)
		{	
			for(int l=0; l< this.numAgents; l++)
			{
				eachRoundResults[j][l]= 1000; // initialising the result of deliberation steps--the value chosen for debugging purposes
			}
		}
		for(int w=0; w< this.numAgents; w++)
		{
			eachRoundResults[0][w]=LastRoundResults[w]; //setting the votes at step zero (before this round starts) as the final values of last round
		}
		//calculating updated votes at this round of the deliberation
		for(int j=1; j< this.numAgents+1; j++) // enumerating through steps of this round of deliberation--step j is when the j-th speaker announces their vote
		{
			for(int l=0; l< this.numAgents; l++) //calculating updated vote of agents at step j
			{
				eachRoundResults[j][l]= DPupdate(eachRoundResults[j-1][j-1],eachRoundResults[j-1][l],  LastEffectiveReliabilities[l][j-1],  LastEffectiveReliabilities[l][l]);
				//resulting vote for agent l after DP update with opinion announced in step j (i.e. vote of  j-th speaker)
			}
		}	
		for(int w=0; w< this.numAgents; w++)
		{
			DelibRoundsResults[i][w]=eachRoundResults[this.numAgents][w];
			// the result of updates at the end of round i
		}
	}
	return DelibRoundsResults[numDelibRounds];
}

//-----------------------------------------------------Deliberation with DP distance on strict orders------------------------------------------------

public int[] DelibStDP(int[] votes)    //takes as input a set of integers between 0-12 representing the agents chosen ranking
{
	int[][] DelibRoundsResults= new int[this.numDelibRounds+1][this.numAgents]; //resulting profiles at each round of deliberation
	int[][] eachRoundResults= new int[this.numAgents+1][this.numAgents]; //resulting profiles at each step of a round of deliberation
	double[][] LastEffectiveReliabilities= new double[this.numAgents][this.numAgents];	//reliabilities assigned to agents by other agents
	for(int k=0; k< this.numAgents; k++)
	{
		DelibRoundsResults[0][k]= votes[k]; //initial profile (round zero)
	}	
	for(int i=1; i<numDelibRounds+1; i++) //calculating results for each round
	{
		int[] LastRoundResults=new int[this.numAgents];
		for(int w=0; w< this.numAgents; w++)
		{
			LastRoundResults[w]=DelibRoundsResults[i-1][w]; //taking the results of last round
		}	
		for(int k=0; k< this.numAgents; k++)
		{
			this.EachRoundReliabilities[i-1][k][k]=this.initialRel[k]; //assigning initial self reliabilities
		}
		for(int s=0; s<this.numAgents; s++ )
		{
			for(int w=0; w < this.numAgents; w++)
			{
				if(w!=s)
				{
					this.EachRoundReliabilities[i-1][s][w]= initialRel2[s];
					//assigning reliabilities by the agent w to other agents. all agents assign same reliabilities to every other agent in every round -- to change if assigning different estimated reliabilities in each round
				}
			}
		}
		LastEffectiveReliabilities=EachRoundReliabilities[i-1];	//reliabilities to be used-- currently remain the same in all rounds
		for(int j=0; j< this.numAgents+1; j++)
		{	
			for(int l=0; l< this.numAgents; l++)
			{
				eachRoundResults[j][l]= 1000; // initialising the result of deliberations teps--the value chosen for debugging purposes
			}
		}
		for(int w=0; w< this.numAgents; w++)
		{
			eachRoundResults[0][w]=LastRoundResults[w]; //setting the votes at step zero (before this round starts) as the final values of last round
		}
	//calculating updated votes at this round of the deliberation
	for(int j=1; j< this.numAgents+1; j++) // enumerating through steps of this round of deliberation--step j is when the j-th speaker announces their vote
	{
			for(int l=0; l< this.numAgents; l++) //calculating updated vote of agents at step j
			{
				eachRoundResults[j][l]= DPStupdate(eachRoundResults[j-1][j-1],eachRoundResults[j-1][l],  LastEffectiveReliabilities[l][j-1],  LastEffectiveReliabilities[l][l]);
				//resulting vote for agent l after DP strict update with opinion announced in step j (i.e. vote of  j-th speaker)
			}
		}	
		for(int w=0; w< this.numAgents; w++)
		{
			DelibRoundsResults[i][w]=eachRoundResults[this.numAgents][w];
			// the result of updates at the end of round i
		}
	}
	return DelibRoundsResults[numDelibRounds];
}

//-----------------------------------------------------Deliberation with DP distance random order------------------------------------------------

public int[] DelibDPRandom(int[] votes) //takes as input a set of integers between 0-12 representing the agents chosen ranking
{
	int[][] DelibRoundsResults= new int[this.numDelibRounds+1][this.numAgents];//resulting profiles at each round of deliberation
	int[][] eachRoundResults= new int[this.numAgents+1][this.numAgents];//resulting profiles at each step of a round of deliberation
	double[][] LastEffectiveReliabilities= new double[this.numAgents][this.numAgents];//reliabilities assigned to agents by other agents
	int[] Agents= new int[this.numAgents];
	for(int o=0; o< this.numAgents; o++)
	{
		Agents[o]=o;
	}
	for(int k=0; k< this.numAgents; k++)
	{
		DelibRoundsResults[0][k]= votes[k]; //initial profile (round zero)
	}	
	for(int i=1; i<numDelibRounds+1; i++) //calculating results at each round
		{
		int index, temp; //randomising agents
		   Random random = new Random();
		   for (int l = this.numAgents - 1; l > 0; l--)
		   {
			   index = random.nextInt(l + 1);
		       temp = Agents[index];
		       Agents[index] = Agents[l];
		       Agents[l] = temp;
		   }		
		int[] LastRoundResults=new int[this.numAgents];
		for(int w=0; w< this.numAgents; w++)
		{
			LastRoundResults[w]=DelibRoundsResults[i-1][w]; //taking the results of last round
		}	
		for(int k=0; k< this.numAgents; k++)
		{
			this.EachRoundReliabilities[i-1][k][k]=this.initialRel[k]; //assigning initial self reliabilities
		}
		for(int s=0; s<this.numAgents; s++ )
		{
			for(int w=0; w < this.numAgents; w++)
			{
				if(w!=s)
				{
					this.EachRoundReliabilities[i-1][s][w]= initialRel2[s];
					//assigning reliabilities by the agent w to other agents. all agents assign same reliabilities to every other agent in every round -- to change if assigning different estimated reliabilities in each round
				}
			}
		}
		LastEffectiveReliabilities=EachRoundReliabilities[i-1]; //reliabilities to be used-- currently remain the same in all rounds
		for(int j=0; j< this.numAgents+1; j++)
		{		
			for(int l=0; l< this.numAgents; l++)
			{
				eachRoundResults[j][l]= 1000; // initialising the result of deliberation steps--the value chosen for debugging purposes
			}
		}
		for(int w=0; w< this.numAgents; w++)
		{
			eachRoundResults[0][w]=LastRoundResults[w]; //setting the votes at step zero (before this round starts) as the final values of last round
		}
			//calculating updated votes at this round of the deliberation
		for(int j=1; j< this.numAgents+1; j++) // enumerating through steps of this round of deliberation--step j is when the j-th speaker announces their vote
		{
			for(int l=0; l< this.numAgents; l++) //calculating updated vote of agents at step j
			{
				eachRoundResults[j][l]= DPupdate(eachRoundResults[j-1][Agents[j-1]],eachRoundResults[j-1][l],  LastEffectiveReliabilities[l][Agents[j-1]],  LastEffectiveReliabilities[l][l]);
				//resulting vote for agent l after DP update with opinion announced in step j (i.e. vote of  j-th speaker)
			}
		}
		for(int w=0; w< this.numAgents; w++)
		{
			DelibRoundsResults[i][w]=eachRoundResults[this.numAgents][w];
			// the result of updates at the end of round i
		}
	}
return DelibRoundsResults[numDelibRounds];
}

//-----------------------------------------------------Deliberation with DP distance strict orders random order------------------------------------------------

public int[] DelibStDPRandom(int[] votes) //takes as input a set of integers between 0-12 representing the agents chosen ranking
{
	int[][] DelibRoundsResults= new int[this.numDelibRounds+1][this.numAgents];//resulting profiles at each round of deliberation
	int[][] eachRoundResults= new int[this.numAgents+1][this.numAgents];//resulting profiles at each step of a round of deliberation
	double[][] LastEffectiveReliabilities= new double[this.numAgents][this.numAgents];//reliabilities assigned to agents by other agents
	int[] Agents= new int[this.numAgents];
	for(int o=0; o< this.numAgents; o++)
	{
		Agents[o]=o;
	}
	for(int k=0; k< this.numAgents; k++)
	{
		DelibRoundsResults[0][k]= votes[k];//initial profile (round zero)
	}	
	for(int i=1; i<numDelibRounds+1; i++) //calculating results at each round
	{
		int index, temp; //randomising agents
		Random random = new Random();
		for (int l = this.numAgents - 1; l > 0; l--)
		{
			index = random.nextInt(l + 1);
			temp = Agents[index];
			Agents[index] = Agents[l];
			Agents[l] = temp;
		   }		
		int[] LastRoundResults=new int[this.numAgents];
		for(int w=0; w< this.numAgents; w++) //taking the results of last round
		{
			LastRoundResults[w]=DelibRoundsResults[i-1][w];
		}		
		for(int k=0; k< this.numAgents; k++)
		{
			this.EachRoundReliabilities[i-1][k][k]=this.initialRel[k]; //assigning initial self reliabilities
		}
		for(int s=0; s<this.numAgents; s++ )
		{
			for(int w=0; w < this.numAgents; w++)
			{
				if(w!=s)
				{
					this.EachRoundReliabilities[i-1][s][w]= initialRel2[s];
					//assigning reliabilities by the agent w to other agents. all agents assign same reliabilities to every other agent in every round -- to change if assigning different estimated reliabilities in each round
				}
			}
		}
		LastEffectiveReliabilities=EachRoundReliabilities[i-1]; //reliabilities to be used-- currently remain the same in all rounds
		for(int j=0; j< this.numAgents+1; j++)
		{
			for(int l=0; l< this.numAgents; l++)
			{
				eachRoundResults[j][l]= 1000; // initialising the result of deliberation steps--the value chosen for debugging purposes
			}
		}
		for(int w=0; w< this.numAgents; w++)
		{
			eachRoundResults[0][w]=LastRoundResults[w]; //setting the votes at step zero (before this round starts) as the final values of last round
		}
		//calculating updated votes at this round of the deliberation
		for(int j=1; j< this.numAgents+1; j++) // enumerating through steps of this round of deliberation--step j is when the j-th speaker announces their vote
		{
			for(int l=0; l< this.numAgents; l++) //calculating updated vote of agents at step j
			{
				eachRoundResults[j][l]= DPStupdate(eachRoundResults[j-1][Agents[j-1]],eachRoundResults[j-1][l],  LastEffectiveReliabilities[l][Agents[j-1]],  LastEffectiveReliabilities[l][l]);
				//resulting vote for agent l after DP strict update with opinion announced in step j (i.e. vote of  j-th speaker)
			}
		}
		for(int w=0; w< this.numAgents; w++)
		{
			DelibRoundsResults[i][w]=eachRoundResults[this.numAgents][w];
			// the result of updates at the end of round i
		}
	}	
return DelibRoundsResults[numDelibRounds];
}

//----------------------------------------------------Deliberation KS fixed order-------------------------------------------------
public int[] DelibKS(int[] votes) //takes as input a set of integers between 0-12 representing the agents chosen ranking
{
	int[][] DelibRoundsResults= new int[this.numDelibRounds+1][this.numAgents]; //resulting profiles at each round of deliberation
	int[][] eachRoundResults= new int[this.numAgents+1][this.numAgents];//resulting profiles at each step of a round of deliberation
	double[][] LastEffectiveReliabilities= new double[this.numAgents][this.numAgents];	//reliabilities assigned to agents by other agents
	for(int k=0; k< this.numAgents; k++)
	{
	DelibRoundsResults[0][k]= votes[k]; //initial profile (round zero)
	}	
	for(int i=1; i<numDelibRounds+1; i++) //calculating results at each round
	{
		int[] LastRoundResults=new int[this.numAgents];
		for(int w=0; w< this.numAgents; w++) //taking the results of last round
		{
			LastRoundResults[w]=DelibRoundsResults[i-1][w];
		}
		for(int k=0; k< this.numAgents; k++)
		{
			this.EachRoundReliabilities[i-1][k][k]=this.initialRel[k]; //assigning initial self reliabilities
		}
		for(int s=0; s<this.numAgents; s++ )
		{
			for(int w=0; w < this.numAgents; w++)
			{
				if(w!=s)
				{
					this.EachRoundReliabilities[i-1][s][w]= initialRel2[s];
					//assigning reliabilities by the agent w to other agents. all agents assign same reliabilities to every other agent in every round -- to change if assigning different estimated reliabilities in each round
				}
			}
		}
		LastEffectiveReliabilities=EachRoundReliabilities[i-1];		//reliabilities to be used-- currently remain the same in all rounds
		for(int j=0; j< this.numAgents+1; j++)
		{		
			for(int l=0; l< this.numAgents; l++)
			{
				eachRoundResults[j][l]= 1000; // initialising the result of deliberation steps--the value chosen for debugging purposes
			}
		}
		for(int w=0; w< this.numAgents; w++)
		{
			eachRoundResults[0][w]=LastRoundResults[w];//setting the votes at step zero (before this round starts) as the final values of last round
		}
		//calculating updated votes at this round of the deliberation
		for(int j=1; j< this.numAgents+1; j++) // enumerating through steps of this round of deliberation--step j is when the j-th speaker announces their vote
		{
			for(int l=0; l< this.numAgents; l++) //calculating updated vote of agents at step j
			{
				eachRoundResults[j][l]= KSupdate(eachRoundResults[j-1][j-1],eachRoundResults[j-1][l],  LastEffectiveReliabilities[l][j-1],  LastEffectiveReliabilities[l][l]);
				//resulting vote for agent l after KS update with opinion announced in step j (i.e. vote of  j-th speaker)
			}
		}		
		for(int w=0; w< this.numAgents; w++)
		{
			DelibRoundsResults[i][w]=eachRoundResults[this.numAgents][w];
			// the result of updates at the end of round i

		}
	}
return DelibRoundsResults[numDelibRounds];
}
//----------------------------------------------------Deliberation KS fixed order strict rankings-------------------------------------------------
public int[] DelibStKS(int[] votes) //takes as input a set of integers between 0-12 representing the agents chosen ranking
{
	int[][] DelibRoundsResults= new int[this.numDelibRounds+1][this.numAgents];//resulting profiles at each round of deliberation
	int[][] eachRoundResults= new int[this.numAgents+1][this.numAgents];//resulting profiles at each step of a round of deliberation
	double[][] LastEffectiveReliabilities= new double[this.numAgents][this.numAgents];//reliabilities assigned to agents by other agents
	
	for(int k=0; k< this.numAgents; k++)
	{
		DelibRoundsResults[0][k]= votes[k]; //initial profile (round zero)
	}
	
	for(int i=1; i<numDelibRounds+1; i++) //calculating results at each round
	{	
		int[] LastRoundResults=new int[this.numAgents];
		for(int w=0; w< this.numAgents; w++) //taking the results of last round
		{
			LastRoundResults[w]=DelibRoundsResults[i-1][w];
		}	
		for(int k=0; k< this.numAgents; k++)
		{
			this.EachRoundReliabilities[i-1][k][k]=this.initialRel[k]; //assigning initial self reliabilities
		}
		for(int s=0; s<this.numAgents; s++ )
		{
			for(int w=0; w < this.numAgents; w++)
			{
				if(w!=s)
				{
					this.EachRoundReliabilities[i-1][s][w]= initialRel2[s];
					//assigning reliabilities by the agent w to other agents. all agents assign same reliabilities to every other agent in every round -- to change if assigning different estimated reliabilities in each round
				}
			}
		}
		LastEffectiveReliabilities=EachRoundReliabilities[i-1];		//reliabilities to be used-- currently remain the same in all rounds
		for(int j=0; j< this.numAgents+1; j++)
		{
		
			for(int l=0; l< this.numAgents; l++)
			{
				eachRoundResults[j][l]= 1000; // initialising the result of deliberation steps--the value chosen for debugging purposes
			}
		}
		for(int w=0; w< this.numAgents; w++)
		{
			eachRoundResults[0][w]=LastRoundResults[w];//setting the votes at step zero (before this round starts) as the final values of last round
		}
		//calculating updated votes at this round of the deliberation
		for(int j=1; j< this.numAgents+1; j++) // enumerating through steps of this round of deliberation--step j is when the j-th speaker announces their vote
		{
			for(int l=0; l< this.numAgents; l++) //calculating updated vote of agents at step j
			{
				eachRoundResults[j][l]= KSStupdate(eachRoundResults[j-1][j-1],eachRoundResults[j-1][l],  LastEffectiveReliabilities[l][j-1],  LastEffectiveReliabilities[l][l]);
				//resulting vote for agent l after KS strict update with opinion announced in step j (i.e. vote of  j-th speaker)
			}
		}		
		for(int w=0; w< this.numAgents; w++)
		{
			DelibRoundsResults[i][w]=eachRoundResults[this.numAgents][w];
			// the result of updates at the end of round i

		}
	}
return DelibRoundsResults[numDelibRounds];
}


//-----------------------------------------------Deliberation with KS-random order-----------------------------------------------------
public int[] DelibKSRandom(int[] votes) //takes as input a set of integers between 0-12 representing the agents chosen ranking
{
	int[][] DelibRoundsResults= new int[this.numDelibRounds+1][this.numAgents];//resulting profiles at each round of deliberation
	int[][] eachRoundResults= new int[this.numAgents+1][this.numAgents];//resulting profiles at each step of a round of deliberation
	double[][] LastEffectiveReliabilities= new double[this.numAgents][this.numAgents];//reliabilities assigned to agents by other agents
	int[] Agents= new int[this.numAgents];
	
	for(int o=0; o< this.numAgents; o++)
	{
		Agents[o]=o;
	}
	for(int k=0; k< this.numAgents; k++)
	{
		DelibRoundsResults[0][k]= votes[k]; //initial profile (round zero)
	}
	
	for(int i=1; i<numDelibRounds+1; i++) //calculating results at each round
	{
		int index, temp; //randomising agents
		Random random = new Random();
		for (int l = this.numAgents - 1; l > 0; l--)
		{
			index = random.nextInt(l + 1);
		    temp = Agents[index];
		    Agents[index] = Agents[l];
		    Agents[l] = temp;
		}
		int[] LastRoundResults=new int[this.numAgents];
		for(int w=0; w< this.numAgents; w++) //taking the results of last round
		{
			LastRoundResults[w]=DelibRoundsResults[i-1][w];
		}		
		for(int k=0; k< this.numAgents; k++)
		{
			this.EachRoundReliabilities[i-1][k][k]=this.initialRel[k]; //assigning initial self reliabilities
		}
		for(int s=0; s<this.numAgents; s++ )
		{
			for(int w=0; w < this.numAgents; w++)
			{
				if(w!=s)
				{
					this.EachRoundReliabilities[i-1][s][w]= initialRel2[s];
					//assigning reliabilities by the agent w to other agents. all agents assign same reliabilities to every other agent in every round -- to change if assigning different estimated reliabilities in each round
				}
			}
		}
		LastEffectiveReliabilities=EachRoundReliabilities[i-1]; //reliabilities to be used-- currently remain the same in all rounds
		for(int j=0; j< this.numAgents+1; j++)
		{	
			for(int l=0; l< this.numAgents; l++)
			{
				eachRoundResults[j][l]= 1000; // initialising the result of deliberation steps--the value chosen for debugging purposes
			}
		}
		for(int w=0; w< this.numAgents; w++)
		{
			eachRoundResults[0][w]=LastRoundResults[w]; //setting the votes at step zero (before this round starts) as the final values of last round
		}
		//calculating updated votes at this round of the deliberation
		for(int j=1; j< this.numAgents+1; j++) // enumerating through steps of this round of deliberation--step j is when the j-th speaker announces their vote
		{
			for(int l=0; l< this.numAgents; l++) //calculating updated vote of agents at step j
			{
				eachRoundResults[j][l]= KSupdate(eachRoundResults[j-1][Agents[j-1]],eachRoundResults[j-1][l],  LastEffectiveReliabilities[l][Agents[j-1]],  LastEffectiveReliabilities[l][l]);
				//resulting vote for agent l after KS update with opinion announced in step j (i.e. vote of  j-th speaker)
			}
		}
		for(int w=0; w< this.numAgents; w++)
		{
			DelibRoundsResults[i][w]=eachRoundResults[this.numAgents][w];
			// the result of updates at the end of round i

		}
	}	
	return DelibRoundsResults[numDelibRounds];
}

//-----------------------------------------------Deliberation with KS-random order---strict rankings--------------------------------------------------
public int[] DelibStKSRandom(int[] votes) //takes as input a set of integers between 0-12 representing the agents chosen ranking
{
	int[][] DelibRoundsResults= new int[this.numDelibRounds+1][this.numAgents];//resulting profiles at each round of deliberation
	int[][] eachRoundResults= new int[this.numAgents+1][this.numAgents]; //resulting profiles at each step of a round of deliberation
	double[][] LastEffectiveReliabilities= new double[this.numAgents][this.numAgents];//reliabilities assigned to agents by other agents
	int[] Agents= new int[this.numAgents];	
	for(int o=0; o< this.numAgents; o++)
	{
	Agents[o]=o;
	}
	for(int k=0; k< this.numAgents; k++)
	{
	DelibRoundsResults[0][k]= votes[k]; //initial profile (round zero)
	}
	
	for(int i=1; i<numDelibRounds+1; i++) //calculating results at each round
	{
		int index, temp; //randomising agents
		   Random random = new Random();
		   for (int l = this.numAgents - 1; l > 0; l--)
		   {
		       index = random.nextInt(l + 1);
		       temp = Agents[index];
		       Agents[index] = Agents[l];
		       Agents[l] = temp;
		   }	
		 int[] LastRoundResults=new int[this.numAgents];
		 for(int w=0; w< this.numAgents; w++) //taking the results of last round
		 {
			 LastRoundResults[w]=DelibRoundsResults[i-1][w];
		 }		
		 for(int k=0; k< this.numAgents; k++)
		 {
			 this.EachRoundReliabilities[i-1][k][k]=this.initialRel[k]; //assigning initial self reliabilities
		 }
		 for(int s=0; s<this.numAgents; s++ )
		 {
			 for(int w=0; w < this.numAgents; w++)
			 {
				 if(w!=s)
				 {
					 this.EachRoundReliabilities[i-1][s][w]= initialRel2[s];
					 //assigning reliabilities by the agent w to other agents. all agents assign same reliabilities to every other agent in every round -- to change if assigning different estimated reliabilities in each round
				 }
			 }
		 }
		 LastEffectiveReliabilities=EachRoundReliabilities[i-1]; //reliabilities to be used-- currently remain the same in all rounds
		 for(int j=0; j< this.numAgents+1; j++)
		 {
			 for(int l=0; l< this.numAgents; l++)
			 {
				 eachRoundResults[j][l]= 1000; // initialising the result of deliberation steps--the value chosen for debugging purposes
			 }
		}
		for(int w=0; w< this.numAgents; w++)
		{
			eachRoundResults[0][w]=LastRoundResults[w]; //setting the votes at step zero (before this round starts) as the final values of last round
		}
		//calculating updated votes at this round of the deliberation
		for(int j=1; j< this.numAgents+1; j++) // enumerating through steps of this round of deliberation--step j is when the j-th speaker announces their vote
		{
			for(int l=0; l< this.numAgents; l++) //calculating updated vote of agents at step j
			{
				eachRoundResults[j][l]= KSStupdate(eachRoundResults[j-1][Agents[j-1]],eachRoundResults[j-1][l],  LastEffectiveReliabilities[l][Agents[j-1]],  LastEffectiveReliabilities[l][l]);
				//resulting vote for agent l after KS strict update with opinion announced in step j (i.e. vote of  j-th speaker)
			}
		}
		for(int w=0; w< this.numAgents; w++)
		{
			DelibRoundsResults[i][w]=eachRoundResults[this.numAgents][w];
			// the result of updates at the end of round i

		}
	}	
	return DelibRoundsResults[numDelibRounds];
}

//----------------------------------------------------Deliberation CS fixed order-------------------------------------------------
public int[] DelibCS(int[] votes) //takes as input a set of integers between 0-12 representing the agents chosen ranking
{
	int[][] DelibRoundsResults= new int[this.numDelibRounds+1][this.numAgents];//resulting profiles at each round of deliberation
	int[][] eachRoundResults= new int[this.numAgents+1][this.numAgents];//resulting profiles at each step of a round of deliberation
	double[][] LastEffectiveReliabilities= new double[this.numAgents][this.numAgents];//reliabilities assigned to agents by other agents
	
	for(int k=0; k< this.numAgents; k++)
	{
		DelibRoundsResults[0][k]= votes[k]; //initial profile (round zero)
	}	
	for(int i=1; i<numDelibRounds+1; i++) //calculating results at each round
	{	
		int[] LastRoundResults=new int[this.numAgents];
		for(int w=0; w< this.numAgents; w++) //taking the results of last round
		{
			LastRoundResults[w]=DelibRoundsResults[i-1][w];
		}
		for(int k=0; k< this.numAgents; k++)
		{
			this.EachRoundReliabilities[i-1][k][k]=this.initialRel[k]; //assigning initial self reliabilities
		}
		for(int s=0; s<this.numAgents; s++ )
		{
			for(int w=0; w < this.numAgents; w++)
			{
				if(w!=s)
				{
					this.EachRoundReliabilities[i-1][s][w]= initialRel2[s];
					//assigning reliabilities by the agent w to other agents. all agents assign same reliabilities to every other agent in every round -- to change if assigning different estimated reliabilities in each round
				}
			}
		}
		LastEffectiveReliabilities=EachRoundReliabilities[i-1];	 //reliabilities to be used-- currently remain the same in all rounds
		for(int j=0; j< this.numAgents+1; j++)
		{	
			for(int l=0; l< this.numAgents; l++)
			{
			eachRoundResults[j][l]= 1000;
			}
		}
		for(int w=0; w< this.numAgents; w++)
		{
			eachRoundResults[0][w]=LastRoundResults[w]; //setting the votes at step zero (before this round starts) as the final values of last round
		}
		//calculating updated votes at this round of the deliberation
		for(int j=1; j< this.numAgents+1; j++) // enumerating through steps of this round of deliberation--step j is when the j-th speaker announces their vote
		{
			for(int l=0; l< this.numAgents; l++) //calculating updated vote of agents at step j
			{
				eachRoundResults[j][l]= CSupdate(eachRoundResults[j-1][j-1],eachRoundResults[j-1][l],  LastEffectiveReliabilities[l][j-1],  LastEffectiveReliabilities[l][l]);
				//resulting vote for agent l after CS update with opinion announced in step j (i.e. vote of  j-th speaker)

			}
		}
		for(int w=0; w< this.numAgents; w++)
		{
			DelibRoundsResults[i][w]=eachRoundResults[this.numAgents][w];
			// the result of updates at the end of round i

		}
	}	
	return DelibRoundsResults[numDelibRounds];
}
//----------------------------------------------------Deliberation CS fixed order strict rankings-----------------------------------------------
public int[] DelibStCS(int[] votes) //takes as input a set of integers between 0-12 representing the agents chosen ranking
{
	int[][] DelibRoundsResults= new int[this.numDelibRounds+1][this.numAgents];//resulting profiles at each round of deliberation
	int[][] eachRoundResults= new int[this.numAgents+1][this.numAgents];//resulting profiles at each step of a round of deliberation
	double[][] LastEffectiveReliabilities= new double[this.numAgents][this.numAgents];	//reliabilities assigned to agents by other agents
	for(int k=0; k< this.numAgents; k++)
	{
		DelibRoundsResults[0][k]= votes[k]; //initial profile (round zero)
	}	
	for(int i=1; i<numDelibRounds+1; i++) //calculating results at each round
	{
		int[] LastRoundResults=new int[this.numAgents];
		for(int w=0; w< this.numAgents; w++) //taking the results of last round
		{
			LastRoundResults[w]=DelibRoundsResults[i-1][w];
		}	
		for(int k=0; k< this.numAgents; k++)
		{
			this.EachRoundReliabilities[i-1][k][k]=this.initialRel[k]; //assigning initial self reliabilities
		}
		for(int s=0; s<this.numAgents; s++ )
		{
			for(int w=0; w < this.numAgents; w++)
			{
				if(w!=s)
				{
					this.EachRoundReliabilities[i-1][s][w]= initialRel2[s];
					//assigning reliabilities by the agent w to other agents. all agents assign same reliabilities to every other agent in every round -- to change if assigning different estimated reliabilities in each round
				}
			}
		}
		LastEffectiveReliabilities=EachRoundReliabilities[i-1]; //reliabilities to be used-- currently remain the same in all rounds
		for(int j=0; j< this.numAgents+1; j++)
		{		
			for(int l=0; l< this.numAgents; l++)
			{
				eachRoundResults[j][l]= 1000; // initialising the result of deliberation steps--the value chosen for debugging purposes
			}
		}
		for(int w=0; w< this.numAgents; w++)
		{
			eachRoundResults[0][w]=LastRoundResults[w]; //setting the votes at step zero (before this round starts) as the final values of last round
		}
		//calculating updated votes at this round of the deliberation
		for(int j=1; j< this.numAgents+1; j++) // enumerating through steps of this round of deliberation--step j is when the j-th speaker announces their vote
		{
			for(int l=0; l< this.numAgents; l++) //calculating updated vote of agents at step j
			{
				eachRoundResults[j][l]= CSStupdate(eachRoundResults[j-1][j-1],eachRoundResults[j-1][l],  LastEffectiveReliabilities[l][j-1],  LastEffectiveReliabilities[l][l]);
				//resulting vote for agent l after CS strict update with opinion announced in step j (i.e. vote of  j-th speaker)
			}
		}	
		for(int w=0; w< this.numAgents; w++)
		{
			DelibRoundsResults[i][w]=eachRoundResults[this.numAgents][w];
			//the result of updates at the end of round i	
		}
	}	
	return DelibRoundsResults[numDelibRounds];
}

//-----------------------------------------------------Deliberation with CS distance random order------------------------------------------------

public int[] DelibCSRandom(int[] votes) //takes as input a set of integers between 0-12 representing the agents chosen ranking
{
	int[][] DelibRoundsResults= new int[this.numDelibRounds+1][this.numAgents];//resulting profiles at each round of deliberation
	int[][] eachRoundResults= new int[this.numAgents+1][this.numAgents];//resulting profiles at each step of a round of deliberation
	double[][] LastEffectiveReliabilities= new double[this.numAgents][this.numAgents];//reliabilities assigned to agents by other agents
	int[] Agents= new int[this.numAgents];
	
	for(int o=0; o< this.numAgents; o++)
	{
		Agents[o]=o;
	}
	for(int k=0; k< this.numAgents; k++)
	{
		DelibRoundsResults[0][k]= votes[k]; //initial profile (round zero)
	}
	
	for(int i=1; i<numDelibRounds+1; i++) //calculating results at each round
	{
		int index, temp; //randomising agents
		Random random = new Random();
		for (int l = this.numAgents - 1; l > 0; l--)
		{
			index = random.nextInt(l + 1);
			temp = Agents[index];
			Agents[index] = Agents[l];
			Agents[l] = temp;
		}
	
		int[] LastRoundResults=new int[this.numAgents];
		for(int w=0; w< this.numAgents; w++) //taking the results of last round
		{
			LastRoundResults[w]=DelibRoundsResults[i-1][w];
		}
		
		for(int k=0; k< this.numAgents; k++)
		{
			this.EachRoundReliabilities[i-1][k][k]=this.initialRel[k]; //assigning initial self reliabilities
		}
		for(int s=0; s<this.numAgents; s++ )
		{
			for(int w=0; w < this.numAgents; w++)
			{
				if(w!=s)
				{
					this.EachRoundReliabilities[i-1][s][w]= initialRel2[s];
					//assigning reliabilities by the agent w to other agents. all agents assign same reliabilities to every other agent in every round -- to change if assigning different estimated reliabilities in each round
				}
			}
		}
		LastEffectiveReliabilities=EachRoundReliabilities[i-1]; //reliabilities to be used-- currently remain the same in all rounds
		for(int j=0; j< this.numAgents+1; j++)
		{
			for(int l=0; l< this.numAgents; l++)
			{
				eachRoundResults[j][l]= 1000; // initialising the result of deliberation steps--the value chosen for debugging purposes
			}
		}
		for(int w=0; w< this.numAgents; w++)
		{
			eachRoundResults[0][w]=LastRoundResults[w];
			//setting the votes at step zero (before this round starts) as the final values of last round
		}
		//calculating updated votes at this round of the deliberation
		for(int j=1; j< this.numAgents+1; j++) // enumerating through steps of this round of deliberation--step j is when the j-th speaker announces their vote
		{
			for(int l=0; l< this.numAgents; l++) //calculating updated vote of agents at step j
			{
				eachRoundResults[j][l]= CSupdate(eachRoundResults[j-1][Agents[j-1]],eachRoundResults[j-1][l],  LastEffectiveReliabilities[l][Agents[j-1]],  LastEffectiveReliabilities[l][l]);
				//resulting vote for agent l after CS update with opinion announced in step j (i.e. vote of  j-th speaker)

			}
		}
		for(int w=0; w< this.numAgents; w++)
		{
			DelibRoundsResults[i][w]=eachRoundResults[this.numAgents][w];
			//the result of updates at the end of round i

		}
	}
	return DelibRoundsResults[numDelibRounds];
}
//-----------------------------------------------Deliberation with CS-random order strict rankings--------------------------------------------------
public int[] DelibStCSRandom(int[] votes) //takes as input a set of integers between 0-12 representing the agents chosen ranking
{
	int[][] DelibRoundsResults= new int[this.numDelibRounds+1][this.numAgents];//resulting profiles at each round of deliberation
	int[][] eachRoundResults= new int[this.numAgents+1][this.numAgents];//resulting profiles at each step of a round of deliberation
	double[][] LastEffectiveReliabilities= new double[this.numAgents][this.numAgents];//reliabilities assigned to agents by other agents
	int[] Agents= new int[this.numAgents];
	
	for(int o=0; o< this.numAgents; o++)
	{
		Agents[o]=o;
	}
	for(int k=0; k< this.numAgents; k++)
	{
		DelibRoundsResults[0][k]= votes[k]; //initial profile (round zero)
	}
	
	for(int i=1; i<numDelibRounds+1; i++) //calculating results at each round
	{
		int index, temp; //randomising agents
		Random random = new Random();
		for (int l = this.numAgents - 1; l > 0; l--)
		{
			index = random.nextInt(l + 1);
			temp = Agents[index];
			Agents[index] = Agents[l];
			Agents[l] = temp;
		}
	
		int[] LastRoundResults=new int[this.numAgents];
		for(int w=0; w< this.numAgents; w++) //taking the results of last round
		{
			LastRoundResults[w]=DelibRoundsResults[i-1][w];
		}

		for(int k=0; k< this.numAgents; k++)
		{
			this.EachRoundReliabilities[i-1][k][k]=this.initialRel[k]; //assigning initial self reliabilities
		}
		for(int s=0; s<this.numAgents; s++ )
		{
			for(int w=0; w < this.numAgents; w++)
			{
				if(w!=s)
				{
					this.EachRoundReliabilities[i-1][s][w]= initialRel2[s];
					//assigning reliabilities by the agent w to other agents. all agents assign same reliabilities to every other agent in every round -- to change if assigning different estimated reliabilities in each round
				}
			}
		}
		LastEffectiveReliabilities=EachRoundReliabilities[i-1]; //reliabilities to be used-- currently remain the same in all rounds
		for(int j=0; j< this.numAgents+1; j++)
		{
			for(int l=0; l< this.numAgents; l++)
			{
				eachRoundResults[j][l]= 1000; // initialising the result of deliberation steps--the value chosen for debugging purposes
			}
		}
		for(int w=0; w< this.numAgents; w++)
		{
			eachRoundResults[0][w]=LastRoundResults[w]; //setting the votes at step zero (before this round starts) as the final values of last round
		}
		//calculating updated votes at this round of the deliberation
		for(int j=1; j< this.numAgents+1; j++) // enumerating through steps of this round of deliberation--step j is when the j-th speaker announces their vote
		{
			for(int l=0; l< this.numAgents; l++) //calculating updated vote of agents at step j
			{
				eachRoundResults[j][l]= CSStupdate(eachRoundResults[j-1][Agents[j-1]],eachRoundResults[j-1][l],  LastEffectiveReliabilities[l][Agents[j-1]],  LastEffectiveReliabilities[l][l]);
				//resulting vote for agent l after CS strict update with opinion announced in step j (i.e. vote of  j-th speaker)
			}
		}
		for(int w=0; w< this.numAgents; w++)
		{
			DelibRoundsResults[i][w]=eachRoundResults[this.numAgents][w];
			// the result of updates at the end of round i
		}
	}
	return DelibRoundsResults[numDelibRounds];
}

//-------------------------------------------------------checks how many agents prefer alternative i to alternative j in profile vote------------------------------------------------


public int pairwisePrefered(int i, int j,int[] vote)
{
	int count=0;
	for(int k=0; k <vote.length; k++)
	{
		if(this.IndexOf(i, PrefAgg.Rankings[vote[k]]) < this.IndexOf(j, PrefAgg.Rankings[vote[k]])) //adds one to the counter for each agent that has ranked i higher than j
		{
			count=count+1;
		}
	}
	return count;
}

//-------------------------------------------------------checks how many agents weakly prefer alternative i to alternative j in profile vote------------------------------------------------


public int pairwiseWPrefered(int i, int j,int[] vote)
{
	int count=0;
	for(int k=0; k <vote.length; k++)
	{
		if(this.IndexOf(i, PrefAgg.Rankings[vote[k]]) <= this.IndexOf(j, PrefAgg.Rankings[vote[k]])) //adds one to the counter for each agent that has ranked i higher than j
		{
			count=count+1;
		}
	}
	return count;
}


//-----------------------------------------------compares alternative in pairwise majority --------------------------------------------------------------------------------------------------

public boolean[][] pairwisecomparison(int[] vote)
{
	boolean[][] matrix= new boolean[3][3];     //the comparison matrix
	for(int k=0; k <3; k++)
	{
		for(int m=0; m <3; m++)
		{
			//if(pairwisePrefered(k+1,m+1,vote) > pairwisePrefered( m+1, k+1, vote))  //sets entry (i, j) to true if a majority prefers i to j and false otherwise
			if(pairwisePrefered(k+1,m+1,vote) > (this.numAgents/2))  //sets entry (i, j) to true if a majority prefers i to j and false otherwise
			{
				matrix[k][m] =true;
			}else matrix[k][m]=false;
		}
	}
	return matrix;
}


//-----------------------------------------------weak compares alternative in pairwise majority --------------------------------------------------------------------------------------------------

public boolean[][] pairwiseWcomparison(int[] vote)
{
	boolean[][] matrix= new boolean[3][3];     //the comparison matrix
	for(int k=0; k <3; k++)
	{
		for(int m=0; m <3; m++)
		{
			if(pairwiseWPrefered(k+1,m+1,vote) > (this.numAgents/2))  //sets entry (i, j) to true if a majority prefers i to j and false otherwise
			{
				matrix[k][m] =true;
			}else matrix[k][m]=false;
		}
	}
	return matrix;
}
//--------------------------------------------------------------checks for cycles----------------------------------------------------------------------------------------------

public boolean checkforCycles(int[] vote)
{
	boolean result=false;
	boolean[][] matrix= new boolean[3][3];
	matrix=this.pairwiseWcomparison(vote);
	int counter=0;
	for(int k=0; k <3; k++)
	{
		for(int m=0; m <3; m++)
		{
			for(int n=0; n <3; n++)
			{
				if(matrix[k][m] == true & matrix[m][k] == false & matrix[m][n]== true & matrix[n][m] == false & matrix[n][k]==true)  //checks if there are i,j and k that form a cycle in pairwise majority voting
				{
					result= true;
					counter=counter+1;
				}
			}
		}
	}
	return result;
}


//-------------------------------------------------------------checks for non transitivity----------------------------------------------------------------------------------------------

public boolean checkforNtran(int[] vote)
{
	boolean result=false;
	boolean[][] matrix= new boolean[3][3];
	matrix=this.pairwiseWcomparison(vote);
	for(int k=0; k <3; k++)
	{
		for(int m=0; m <3; m++)
		{
			for(int n=0; n <3; n++)
			{
				if(matrix[k][m] == true & matrix[m][n]== true & matrix[k][n]==false) //checks if there are i,j and k that form a cycle in pairwise majority voting
				{
					result=true;
				}
			}
		}
	}
	return result;
}


//--------------------------------------------------------------checks for clusters----------------------------------------------------------------------------------------------

public static int[] clustersizes(int[] votes)
{
	int size= votes.length;
	int[] clusters=new int[13];
	for(int j=0; j<13; j++)
	{
		clusters[j]=0;
	}
	for(int i=0; i<size; i++)
	{
		clusters[votes[i]]= clusters[votes[i]]+1;
	}
	return clusters;

}
//--------------------------------------------------------------cluster counting----------------------------------------------------------------------------------------------


public int clustercounting(int[] clusters)
{
	int size= clusters.length;
	int count=0;
	for(int j=0; j<size; j++)
	{
		if(clusters[j]!=0)
		{
			count= count+1;
		}
	}
	
return count;
}

//--------------------------------------------------------------counting clusters ----------------------------------------------------------------------------------------------

public int countcluster(int[] votes)
{
	
	int clustercount=1;
	Set<Integer> setvote = new HashSet<Integer>();
	for (Integer x : votes)
	{  
		setvote.add(x);
		clustercount=setvote.size();
	}
	return clustercount;
}

//-------------------------------------------------checks is the final profile after deliberation is in consensus----------------------------------------------------

public boolean checkconsensus(int[] votes)
{
	int[] values=votes;
	for(int i=1; i< this.numAgents; i++)
	{
		if(values[i] != values[0])
			return false;
	}
	return true;
}


//-------------------------------------------------------converting string values to integers----------------------------------------------

public int StringtoInteger(String s)
{
	int u=0;
	if(s.equals("1")) u=1;
	if(s.equals("2")) u=2;
	if(s.equals("3")) u=3;
	if(s.equals("4")) u=4;
	if(s.equals("5")) u=5;
return u;
}

//------------------------------------------checks if a given ranking is single peaked with respect to the ordering "1,2,3" of the alternatives


public boolean singlePeaked(List<String> vote)
{
	if(vote.size()<=2) //if the ranking is not strict it is not single-peaked
	{
		return false;
	}else
	{
		int u=StringtoInteger(vote.get(0)); //taking the alternative ranked highest
		for(int i=1;i<u;i++)   //checking the correct order of rankings for alternatives appearing before the one ranked highest in "vote" (in the dimension "1, 2, 3")  
		{
			for(int j=1; j<i;j++)
			{
				if(i!=j)
				{
					if(IndexOf(i, vote)> IndexOf(j, vote))
					{
						return false;
					}
				}
			}
		}
		for(int i=u+1;i<=3;i++) //checking the correct order of rankings for alternatives appearing after the one ranked highest in "vote" (in the dimension "1, 2, 3")
		{
			for(int j=i; j<=3;j++)
			{
				if(i!=j)
				{
					if(IndexOf(i, vote)> IndexOf(j, vote))
					{
						return false;
					}
				}
			}
		}
	}
	return true;
}

//------------------------------------------checks if a given ranking is weakly single peaked with respect to the ordering "1,2,3" of the alternatives

public boolean WsinglePeaked(List<String> vote)
{
	
	if(vote.equals(PrefAgg.Rankings[2]))
	{
		return false;
	}else if(vote.equals(PrefAgg.Rankings[8]))
	{
		return false;
	}else if(vote.equals(PrefAgg.Rankings[11]))
	{
		return false;
	}else {
		return true;
	}
}

//------------------------------------------checks if a given ranking is single plateau with respect to the ordering "1,2,3" of the alternatives

public boolean SinglePlateau(List<String> vote)
{

	if(vote.equals(PrefAgg.Rankings[0]))
	{
		return false;
	}else if(vote.equals(PrefAgg.Rankings[2]))
	{
		return false;
	}else if(vote.equals(PrefAgg.Rankings[4]))
	{
		return false;
	}else if(vote.equals(PrefAgg.Rankings[6]))
	{
		return false;
	}else if(vote.equals(PrefAgg.Rankings[8]))
	{
		return false;
	}else if(vote.equals(PrefAgg.Rankings[11]))
	{
		return false;
	}else{
		return true;
		}
}


//------------------------------checks if a rankings is single peaked with respect to the given order "ref" assuming that ref is antisymmetric---------------------------------------

public boolean GsinglePeaked(int vote, int ref)
{
	List<String> toCheck= new ArrayList<String>(); //creating an array and initializing it to some arbitrary initial values
	toCheck.add(0, "100");
	toCheck.add(1, "100");
	toCheck.add(2, "100");
	
	if(PrefAgg.Rankings[vote].size()< 3) //if two alternatives are ranked the same then it is not single peaked
	{
		return false;
	}else
	{
	
	//take the given order ref and call the first alternative in the order "1", the second "2" and the third "3"
	//in the ranking vote make the same renaming
	int e1=StringtoInteger(PrefAgg.Rankings[ref].get(0));   //takes the first alternative in the given order called e1
	toCheck.set(this.IndexOf(e1, PrefAgg.Rankings[vote])-1, "1"); //checks the rank of e1 in the given ranking and set the same rank for "1" in the new ranking toCheck
	int e2=StringtoInteger(PrefAgg.Rankings[ref].get(1));
	toCheck.set(this.IndexOf(e2, PrefAgg.Rankings[vote])-1, "2");
	int e3=StringtoInteger(PrefAgg.Rankings[ref].get(2));
	toCheck.set(this.IndexOf(e3, PrefAgg.Rankings[vote])-1, "3");
	}
	
	if(this.singlePeaked(toCheck)) //check the single peakedness of the the created ranking with respect to the canonical ordering 1,2,3
	{
		return true;
	}else return false;
}

//------------------------------checks if a rankings is weakly single peaked with respect to the given order "ref" assuming that ref is antisymmetric---------------------------------------

public boolean GWsinglePeaked(int vote, int ref)
{
	List<String> toCheck= new ArrayList<String>(); //creating an array and initializing it to some arbitrary initial values
	List<String> toCheckf= new ArrayList<String>();
	
	for(int i=0; i<PrefAgg.Rankings[vote].size(); i++)
	{
		toCheck.add(i, "x");
	} //initialising the array to the right length
	
	
	//take the given order ref and call the first alternative in the order "1", the second "2" and the third "3"
	//in the ranking vote make the same renaming
		
	int e1=StringtoInteger(PrefAgg.Rankings[ref].get(0));   //takes the first alternative in the given order called e1
	toCheck.set(this.IndexOf(e1, PrefAgg.Rankings[vote])-1, toCheck.get(this.IndexOf(e1, PrefAgg.Rankings[vote])-1)+"1"); //checks the rank of e1 in the given ranking and set the same rank for "1" in the new ranking toCheck
	int e2=StringtoInteger(PrefAgg.Rankings[ref].get(1));
	toCheck.set(this.IndexOf(e2, PrefAgg.Rankings[vote])-1, toCheck.get(this.IndexOf(e2, PrefAgg.Rankings[vote])-1)+"2");
	int e3=StringtoInteger(PrefAgg.Rankings[ref].get(2));
	toCheck.set(this.IndexOf(e3, PrefAgg.Rankings[vote])-1, toCheck.get(this.IndexOf(e3, PrefAgg.Rankings[vote])-1)+"3");
		
	for(int e=0; e<toCheck.size(); e++)
	{
		toCheckf.add(e, toCheck.get(e).substring(1));
	}

	if(this.WsinglePeaked(toCheckf)) //check the single peakedness of the the created ranking with respect to the canonical ordering 1,2,3
	{
		return true;
	}else return false;
}


//------------------------------checks if a rankings is single plateau with respect to the given order "ref" assuming that ref is antisymmetric---------------------------------------

public boolean GSinglePlateau(int vote, int ref)
{
	List<String> toCheck= new ArrayList<String>(); //creating an array and initializing it to some arbitrary initial values
	List<String> toCheckf= new ArrayList<String>();
	
	for(int i=0; i<PrefAgg.Rankings[vote].size(); i++)
	{
		toCheck.add(i, "x");
	} //initialising the array to the right length
	
	//take the given order ref and call the first alternative in the order "1", the second "2" and the third "3"
	//in the ranking vote make the same renaming
	
	int e1=StringtoInteger(PrefAgg.Rankings[ref].get(0));   //takes the first alternative in the given order called e1
	toCheck.set(this.IndexOf(e1, PrefAgg.Rankings[vote])-1, toCheck.get(this.IndexOf(e1, PrefAgg.Rankings[vote])-1)+"1"); //checks the rank of e1 in the given ranking and set the same rank for "1" in the new ranking toCheck
	int e2=StringtoInteger(PrefAgg.Rankings[ref].get(1));
	toCheck.set(this.IndexOf(e2, PrefAgg.Rankings[vote])-1, toCheck.get(this.IndexOf(e2, PrefAgg.Rankings[vote])-1)+"2");
	int e3=StringtoInteger(PrefAgg.Rankings[ref].get(2));
	toCheck.set(this.IndexOf(e3, PrefAgg.Rankings[vote])-1, toCheck.get(this.IndexOf(e3, PrefAgg.Rankings[vote])-1)+"3");
		
	for(int e=0; e<toCheck.size(); e++)
	{
		toCheckf.add(e, toCheck.get(e).substring(1));
	}
	
	if(this.SinglePlateau(toCheckf)) //check the single peakedness of the the created ranking with respect to the canonical ordering 1,2,3
	{
		return true;
	}else return false;
}

//------------------------------checks if a profile of rankings is single peaked with respect to the given order "ref"---------------------------------------------------------

public boolean singlePeakedProfile(int[] votes, int ref)
{
	int length=votes.length;
	int counter=0;
	for(int i=0; i<length; i++)
	{
		if(GsinglePeaked(votes[i], ref))
			counter=counter+1;
	}	
	if(counter ==length) {return true;}else {return false;} // the profile is single peaked if 75% of the rankings therein are single peaked
}

//------------------------------checks if a profile of rankings is weakly single peaked with respect to the given order "ref"---------------------------------------------------------

public boolean WsinglePeakedProfile(int[] votes, int ref)
{
	int length=votes.length;
	int counter=0;
	for(int i=0; i<length; i++)
	{
		if(GWsinglePeaked(votes[i], ref))
			counter=counter+1;
	}
	
	if(counter ==length) {return true;}else {return false;} // the profile is single peaked if 75% of the rankings therein are single peaked
}

//------------------------------checks if a profile of rankings is single plateau with respect to the given order "ref"---------------------------------------------------------

public boolean SinglePlateauProfile(int[] votes, int ref)
{
	int length=votes.length;
	int counter=0;
	for(int i=0; i<length; i++)
	{
		if(GSinglePlateau(votes[i], ref))
			counter=counter+1;
	}
	if(counter ==length) 
	{
		return true;
	}else {return false;} // the profile is single peaked if 75% of the rankings therein are single peaked
}

//------------------------------checks if a profile of rankings is weakly single peaked with respect to any order "ref"---------------------------------------------------------

public boolean fullWSinglePeaked(int[] votes)
{
	boolean check=false;
	for(int ref=0; ref< 13; ref++)
	{
		if( !check && PrefAgg.Rankings[ref].size()== 3)
		{
			if(this.WsinglePeakedProfile(votes, ref))
			{
				check=true;  //to stop the loop if an ordering is already found with respect to which the votes are single peaked
			}
		}
	}

	return check;
}

//------------------------------checks if a profile of rankings is weakly single peaked with respect to any order "ref"---------------------------------------------------------

public boolean fullSinglePeaked(int[] votes)
{
	boolean check=false;
	for(int ref=0; ref< 13; ref++)
	{
		if( !check && PrefAgg.Rankings[ref].size()== 3)
		{
			if(this.singlePeakedProfile(votes, ref))
			{
				check=true;  //to stop the loop if an ordering is already found with respect to which the votes are single peaked
			}
		}
	}

	return check;
}

//------------------------------------------checks if an ordering 'vote' is  strict------------------------------------


public static boolean strict(List<String> vote)
	{
	if(vote.size()< 3)
	{
		return false;
	}else
	{
		return true;
	}
}
//------------------------------------------checks for strict profiles------------------------------------


public boolean strictprof(int[] vote, int q)
{
	int counter1=0;
	for(int u=0; u< q; u++)
	{
		List<String> z=PrefAgg.Rankings[vote[u]];
		if(strict(z))
		{
			counter1=counter1+1;
		}
	}
	if (counter1 >= (0.74)*q)
	{
		return true;
	}else return false;
}

//---------------------------------------------proximity to weak single peakedness---------------


public double proxWSP(int[] vote)
{
	int groupSize= vote.length;
	int[] SP=new int[6];
	for(int a=0; a<6;a++)
	{
		SP[a]=0;
	}
	for(int j=0; j< 6; j++)
	{
		for(int i=0; i<groupSize; i++)
		{
			if(GWsinglePeaked(vote[i], j+7))
			{
				SP[j]=SP[j]+1;
			}
		}
	}
	int max=0;
	for(int g=0; g<6; g++)
	{
		if(SP[g]> max)
		{
			max=SP[g];
		}
	}
	return ((double) max)/groupSize;
}


//--------------------------------------------proximity to single plateauness----------------


public double proxSP(int[] vote)
{
	int groupSize= vote.length;
	int[] SP=new int[6];
	for(int a=0; a<6;a++)
	{
		SP[a]=0;
	}

	for(int j=0; j< 6; j++)
	{
		for(int i=0; i<groupSize; i++)
		{
			if(GSinglePlateau(vote[i], j+7))
			{
				SP[j]=SP[j]+1;
			}
		}
	}

	int max=0;
	for(int g=0; g<6; g++)
	{
		if(SP[g]> max)
		{
			max=SP[g];
		}
	}
	return ((double) max)/groupSize;
}

//-----------------------------------------proximity to single peakedness-------------------


public double proxSPeak(int[] vote)
{
	int groupSize= vote.length;
	int[] SP=new int[6];
	for(int a=0; a<6;a++)
	{
	 SP[a]=0;
	}	
	for(int j=0; j< 6; j++)
	{	
		for(int i=0; i<groupSize; i++)
		{
			if(GsinglePeaked(vote[i], j+7))
			{
				SP[j]=SP[j]+1;
			}
		}
	}
	int max=0;
	for(int g=0; g<6; g++)
	{
		if(SP[g]> max)
		{
			max=SP[g];
		}
	}
	return ((double) max)/groupSize;
}
//-----------------------------------------------------------------------------------------------------------------------------

public static void main(String[] a)
{
	String outputfile= "/..."; //Path on the computer for the text file that will contain the output
	
	boolean ProximityCalc=true;
	try
	{
		FileWriter fw = new FileWriter(outputfile,true);
		BufferedWriter bw = new BufferedWriter(fw);
		PrintWriter pw = new PrintWriter(bw);
		if(ProximityCalc) {
			pw.println("Nbr of Agents"+","+"Reliabilities"+","+"Starting Cycles"+","+"initially non-transitive"+","+"initial proximity to Strict Sing Peak"+","+"initial proximity to Single Plateau"+","+"DP Nbr Cycles Result"+","+"DP % Cycles Remaining"+","+"DP Avg move 2 cons"+","+"DP Avg Clusters"+","+"DP non-transitive"+","+"DP proximity to Strict Single Peak"+","+"DP Proximity to Single plateau"+","+"DP nontransitive end single plateau"+","+"KS Nbr Cycles Result"+","+"KS % Cycles Remaining"+","+"KS Avg move 2 cons"+","+"KS Avg Clusters"+","+"KS non-transitive"+","+"KS proximity to Strict Single Peak"+","+"KS Proximity to Single Plateau"+","+"KS nontransitive end single plateau"+","+"CS Nbr Cycles Result"+","+"CS % Cycles Remaining"+","+"CS Avg move 2 cons"+","+"CS Avg Clusters"+","+"CS non-transitive"+","+"CS proximity to Strict Single Peak"+","+"CS Proximity to Single Plateau"+","+"CS nontransitive end sing plateau");
		}
		pw.flush();
		pw.close();
	}
	catch (Exception E)
	{
		JOptionPane.showMessageDialog(null,"Data NOT Saved");
	}
	for(int q=3; q<50; q=q+6)   //running the code for different group sizes
	{
		int num=0;
		for(double rel=0.5; rel<1; rel=rel+0.1) //running the code for different reliabilities
		{
			int DPclusters=0;
			int KSclusters=0;
			int CSclusters=0;
			double DPavgclusters=0;
			double KSavgclusters=0;
			double CSavgclusters=0;
				
			int[] DelibResultsKS;
			int[] DelibResultsDP;
			int[] DelibResultsCS;
			int[] votes;
			double[] dis= new double[q];
			int DPconsensuscounter=0;
			int KSconsensuscounter=0;
			int CSconsensuscounter=0;
			int DPcycendSP=0;
			int KScycendSP=0;
			int CScycendSP=0;			
			int DPcycendwSP=0;
			int KScycendwSP=0;
			int CScycendwSP=0;
			int DPNtranendSP=0;
			int KSNtranendSP=0;
			int CSNtranendSP=0;
			int DPNtranendSPla=0;
			int KSNtranendSPla=0;
			int CSNtranendSPla=0;	
			int DPNtranendWSP=0;
			int KSNtranendWSP=0;
			int CSNtranendWSP=0;
			int DPcycendSPla=0;	
			int KScycendSPla=0;
			int CScycendSPla=0;		
			double singlePeakedCounter=0;
			double DPsinglePeakedResultCounter=0;
			double KSsinglePeakedResultCounter=0;
			double CSsinglePeakedResultCounter=0;
			double wsinglePeakedCounter=0;
			double DPwsinglePeakedResultCounter=0;
			double KSwsinglePeakedResultCounter=0;
			double CSwsinglePeakedResultCounter=0;
			double iniSinglePlateau=0;
			double DPSinglePlateau=0;
			double KSSinglePlateau=0;
			double CSSinglePlateau=0;
			double iniProximitytoWSP=0;
			double iniProximitytoSP=0;
			double KSProximitytoSP=0;
			double DPProximitytoSP=0;
			double CSProximitytoSP=0;
			double iniProximitytoSPeak=0;
			double KSProximitytoSPeak=0;
			double DPProximitytoSPeak=0;
			double CSProximitytoSPeak=0;
			double KSWProximitytoSP=0;
			double DPWProximitytoSP=0;
			double CSWProximitytoSP=0;	
			double iniProx=0;
			double KSProx=0;
			double DPProx=0;
			double CSProx=0;
			double iniStProx=0;
			double KSStProx=0;
			double DPStProx=0;
			double CSStProx=0;
			double[] DPinitdistances2Csqr= new double[13];
			double[] KSinitdistances2Csqr= new double[13];
			double[] CSinitdistances2Csqr= new double[13];		
			double[] DPinitdistances2C= new double[13];
			double[] KSinitdistances2C= new double[13];
			double[] CSinitdistances2C= new double[13];	
			double CSinitdist2C=0;
			double KSinitdist2C=0;
			double DPinitdist2C=0;
			double[] DPdistances2Csqr= new double[13];
			double[] KSdistances2Csqr= new double[13];
			double[] CSdistances2Csqr= new double[13];
			double[] DPdistances2C= new double[13];
			double[] KSdistances2C= new double[13];
			double[] CSdistances2C= new double[13];
			double CSresultdist2C=0;
			double KSresultdist2C=0;
			double DPresultdist2C=0;
			double CSdiffdist2C=0;
			double KSdiffdist2C=0;
			double DPdiffdist2C=0;
			double CSmeandiffdist2C=0;
			double KSmeandiffdist2C=0;
			double DPmeandiffdist2C=0;
			double cycremainingCS;
			double cycremainingDP;
			double cycremainingKS;
			int wspcyc=0;
			
	//-------------------------------------------------------------------------------------------------------------------------------------------------------
			int numAg=q;
			double rel2;
			rel2= (1-rel);
			PrefAgg p= new PrefAgg(numAg,rel, rel2, 20);
			for(int l=0; l< numAg; l++)
			{
				dis[l]=0;
			}
	
			double cyc=0;      //counter for initial cycles
			double DPcyc=0; //counter for cycles after DP deliberation
			double KScyc=0;   //counter for cycles after KS deliberation
			double CScyc=0;  //counter for cycles after CS deliberation
			int initNonTransitive=0;
			int DPNtran=0;
			int KSNtran=0;
			int CSNtran=0;
			int numSimulations=1000;
			for(int w=0; w<numSimulations;w++)
			{
				boolean check0=true;
				boolean DPcheck=true;
				boolean KScheck=true;
				boolean CScheck=true;
				boolean wcheck0=true;
				boolean DPwcheck=true;
				boolean KSwcheck=true;
				boolean CSwcheck=true;
				boolean pcheck0=true;
				boolean DPpcheck=true;
				boolean KSpcheck=true;
				boolean CSpcheck=true;
				//votes=p.voting();    //random voting
				votes=p.Stvoting();		//random voting with strict rankings
				// ---------------------------------------------------simulating the deliberation process
				//---------------------------------------------------Deliberation with different measures, Random or fixed order of speakers, and limited to strict rankings or not
				DelibResultsDP= p.DelibDP(votes);			//deliberation with DP
				DelibResultsKS= p.DelibKS(votes);			//deliberation with KS
				DelibResultsCS= p.DelibCS(votes);			//deliberation with CS
				DelibResultsDP= p.DelibStDP(votes);			//deliberation with DP- limited to strict rankings
				DelibResultsKS= p.DelibStKS(votes);			//deliberation with KS- limited to strict rankings
				DelibResultsCS= p.DelibStCS(votes);			//deliberation with CS- limited to strict rankings
				//DelibResultsDP= p.DelibDPRandom(votes);		//deliberation with DP with random order
				//DelibResultsKS= p.DelibKSRandom(votes);		//deliberation with KS with random order
				//DelibResultsCS= p.DelibCSRandom(votes);		//deliberation with CS with random order
				//DelibResultsDP= p.DelibStDPRandom(votes);  	//deliberation with DP, limited to strict rankings-random order
				//DelibResultsKS= p.DelibStKSRandom(votes);		//fordeliberation with KS, limited to strict rankings-random order
				//DelibResultsCS= p.DelibStCSRandom(votes);		//deliberation with CD, limited to strict rankings-random order
				DPclusters= DPclusters+p.countcluster(DelibResultsDP); //number of clusters deliberation with DP over all simulations
				KSclusters= KSclusters+p.countcluster(DelibResultsKS); //number of clusters deliberation with KS over all simulations
				CSclusters= CSclusters+p.countcluster(DelibResultsCS); //number of clusters deliberation with CS over all simulations
				

			
//-------------------------------------------------------------------------------------checking for cycles in initial votes
				if( p.checkforCycles(votes))
				{
					cyc=cyc+1;
					boolean wcheck20=true;
					for(int ref=0; ref< 13; ref++)
					{
						if( wcheck20 && PrefAgg.Rankings[ref].size()== 3)
						{
							if(p.WsinglePeakedProfile(votes, ref))
							{
								wspcyc= wspcyc+1; //adding 1 to the single peaked counter
								wcheck20=false;  //to stop the loop if an ordering is already found with respect to which the votes are single peaked
							}
						}
					}
				}
	//-------------------------------------------------------------------------------------checking for Non transitive initial votes
				if( p.checkforNtran(votes))
				{
					initNonTransitive=initNonTransitive+1;
				}
	//-------------------------------------------------------------------------------------checking for cycles in deliberation results
				if( p.checkforCycles(DelibResultsDP))
				{
					DPcyc=DPcyc+1;
				}
				if( p.checkforCycles(DelibResultsKS))
				{
					KScyc=KScyc+1;
				}
				if( p.checkforCycles(DelibResultsCS))
				{
					CScyc=CScyc+1;
				}
	//---------------------------------------checking for transitivity in deliberation results
				if( p.checkforNtran(DelibResultsDP))
				{
					DPNtran=DPNtran+1;
				}
				if( p.checkforNtran(DelibResultsKS))
				{
					KSNtran=KSNtran+1; 
				}
				if( p.checkforNtran(DelibResultsCS))
				{
					CSNtran=CSNtran+1;
				}
	//------------------------------------checking if initial votes are single peaked with respect to any ordering-------------------------------------------------
				for(int ref=0; ref< 13; ref++)
				{
					if( check0 &&PrefAgg.Rankings[ref].size()== 3)//limiting to those that do not put two alternatives at the same rank and thus give an ordering of three alternatives
					{
						if(p.singlePeakedProfile(votes, ref))
						{
							singlePeakedCounter= singlePeakedCounter+1; //adding 1 to the single peaked counter if the votes are single peaked
							check0=false;  //to stop the loop if an ordering is already found with respect to which the votes are single peaked
	
						}
					}
				}
	//------------------------------------checking if initial votes are weakly single peaked with respect to any ordering-------------------------------------------------
				for(int ref=0; ref< 13; ref++)
				{
					if( wcheck0 && PrefAgg.Rankings[ref].size()== 3)
					{
						if(p.WsinglePeakedProfile(votes, ref))
						{
							wsinglePeakedCounter= wsinglePeakedCounter+1; //adding 1 to the single peaked counter
							wcheck0=false;  //to stop the loop if an ordering is already found with respect to which the votes are single peaked
						}
					}
				}
	//------------------------------------checking if initial votes are single plateau with respect to any ordering-------------------------------------------------
				for(int ref=0; ref< 13; ref++)
				{
					if( pcheck0 &&PrefAgg.Rankings[ref].size()== 3)//limiting to those that do not put two alternatives at the same rank and thus give an ordering of three alternatives
					{
						if(p.SinglePlateauProfile(votes, ref))
						{
							iniSinglePlateau= iniSinglePlateau+1; //adding 1 to the single peaked counter if the votes are single peaked
							pcheck0=false;  //to stop the loop if an ordering is already found with respect to which the votes are single peaked
						}
					}
				}
	//------------------------------------calculating Proximity to weak Single Peakedness-single plateauness and weak single peakedness-------------------------------------------------
				if(ProximityCalc)
				{
					iniProximitytoWSP= iniProximitytoWSP+ p.proxWSP(votes); //to weak Single peakedness initial votes
					iniProximitytoSP= iniProximitytoSP+ p.proxSP(votes); //to Single pelateau
					iniProximitytoSPeak=iniProximitytoSPeak+p.proxSPeak(votes); //to strict Single peakedness
					KSProximitytoSP= KSProximitytoSP+ p.proxSP(DelibResultsKS); //to Single pelateau-after deliberation with KS
					DPProximitytoSP= DPProximitytoSP+ p.proxSP(DelibResultsDP); //to Single pelateau-after deliberation with DP
					CSProximitytoSP= CSProximitytoSP+ p.proxSP(DelibResultsCS);	//to Single pelateaus-after deliberation with CS
					KSWProximitytoSP= KSWProximitytoSP+ p.proxWSP(DelibResultsKS); //to weak Single peakednessu-after deliberation with KS
					DPWProximitytoSP= DPWProximitytoSP+ p.proxWSP(DelibResultsDP); //to weak Single peakednessu-after deliberation with DP
					CSWProximitytoSP= CSWProximitytoSP+ p.proxWSP(DelibResultsCS);  //to weak Single peakednessu-after deliberation with CS
					KSProximitytoSPeak= KSProximitytoSPeak+ p.proxSPeak(DelibResultsKS); //to Single peakednessu-after deliberation with KS
					DPProximitytoSPeak= DPProximitytoSPeak+ p.proxSPeak(DelibResultsDP); //to Single peakednessu-after deliberation with DP
					CSProximitytoSPeak= CSProximitytoSPeak+ p.proxSPeak(DelibResultsCS); //to Single peakednessu-after deliberation with CS
				}
	//--------------------------calculating the distances to consensus------------------------------------------------------------------
				for(int l=0; l<13; l++)
				{
					DPdistances2Csqr[l]=0;    //initializing the array distances2sqr to zero
					KSdistances2Csqr[l]=0;
					CSdistances2Csqr[l]=0;
					DPinitdistances2Csqr[l]=0;    //initializing the array initdistances2sqr to zero
					KSinitdistances2Csqr[l]=0;
					CSinitdistances2Csqr[l]=0;
				}
	////-----------------Calculating distance of the initial vote to consensus----------------------------------------------------
				for(int t=0; t< 13; t++)
				{
					for(int l=0; l<numAg; l++)
					{
						DPinitdistances2Csqr[t]= DPinitdistances2Csqr[t]+Math.pow(PrefAgg.DPDistanceMatrix[t][votes[l]],2);
					}
					for(int l=0; l<numAg; l++)
					{
						KSinitdistances2Csqr[t]= KSinitdistances2Csqr[t]+Math.pow(PrefAgg.KDistanceMatrix[t][votes[l]],2);
					}
					for(int l=0; l<numAg; l++)
					{
						CSinitdistances2Csqr[t]= CSinitdistances2Csqr[t]+Math.pow(PrefAgg.CSDistanceMatrix[t][votes[l]],2);
					}
				}
				for(int t=0; t< 13; t++)
				{
					DPinitdistances2C[t]= Math.sqrt(DPinitdistances2Csqr[t]);
				}
				for(int t=0; t< 13; t++)
				{
					KSinitdistances2C[t]= Math.sqrt(KSinitdistances2Csqr[t]);
				}
				for(int t=0; t< 13; t++)
				{
					CSinitdistances2C[t]= Math.sqrt(CSinitdistances2Csqr[t]);
				}
	////-------------------Calculating distance of the result profile to consensus----------------------------------------------------
				for(int t=0; t< 13; t++)
				{
					for(int l=0; l<numAg; l++)
					{
						DPdistances2Csqr[t]= DPdistances2Csqr[t]+Math.pow(PrefAgg.DPDistanceMatrix[t][DelibResultsDP[l]],2);
					}
					for(int l=0; l<numAg; l++)
					{
						KSdistances2Csqr[t]= KSdistances2Csqr[t]+Math.pow(PrefAgg.KDistanceMatrix[t][DelibResultsKS[l]],2);
					}
					for(int l=0; l<numAg; l++)
					{
						CSdistances2Csqr[t]= CSdistances2Csqr[t]+Math.pow(PrefAgg.CSDistanceMatrix[t][DelibResultsCS[l]],2);
					}
				}
				for(int t=0; t< 13; t++)
				{
					DPdistances2C[t]= Math.sqrt(DPdistances2Csqr[t]);
				}
				for(int t=0; t< 13; t++)
				{
					KSdistances2C[t]= Math.sqrt(KSdistances2Csqr[t]);
				}
				for(int t=0; t< 13; t++)
				{
					CSdistances2C[t]= Math.sqrt(CSdistances2Csqr[t]);
				}
				
//--------------finds the r with the minimal average distance to resulting vote
				int counterCSinit= 0;
				for(int t=1; t<13; t++)
				{
					if(CSinitdistances2C[t]< CSinitdistances2C[counterCSinit]) //initial CS distance to consensus for KS delib. in this round of simul
					{
						counterCSinit= t;
						CSinitdist2C= CSinitdistances2C[t];
					}
				}
				int counterCSres= 0;
				for(int t=1; t<13; t++)
				{
					if(CSdistances2C[t]< CSdistances2C[counterCSres]) //CS distance to consensus in this round of simulation
					{
						counterCSres= t;
						CSresultdist2C= CSdistances2C[t];
					}
				}
				CSdiffdist2C= CSdiffdist2C+(CSinitdist2C - CSresultdist2C); //total move to consensus with CS over all simulations (previous amount + the move in this round of simulation)
				int counterKSinit= 0;
				for(int t=1; t<13; t++)
				{
					if(KSinitdistances2C[t]< KSinitdistances2C[counterKSinit])  //initial KS distance to consensus for KS delib. in this round of simul
					{
						counterKSinit= t;
							KSinitdist2C= KSinitdistances2C[t];
					}
				}
				int counterKSres= 0;
				for(int t=1; t<13; t++)
				{
					if(KSdistances2C[t]< KSdistances2C[counterKSres]) //KS distance to consensus  in this round of simulation
					{
						counterKSres= t;
						KSresultdist2C= KSdistances2C[t];
					}
				}
				KSdiffdist2C= KSdiffdist2C+(KSinitdist2C - KSresultdist2C);//total move to consensus with KS over all simulations (previous amount + the move in this round of simulation)
				int counterDPinit= 0;
				for(int t=1; t<13; t++)
				{
					if(DPinitdistances2C[t]< DPinitdistances2C[counterDPinit]) //initial DP distance to consensus for KS delib. in this round of simulation
					{
						counterDPinit= t;
						DPinitdist2C= DPinitdistances2C[t];
					}
				}
				int counterDPres= 0;
				for(int t=1; t<13; t++)
				{
					if(DPdistances2C[t]< DPdistances2C[counterDPres]) //DP distance to consensus in this round of simulation
					{
						counterDPres= t;
						DPresultdist2C= DPdistances2C[t];
					}
				}
				DPdiffdist2C= DPdiffdist2C+(DPinitdist2C - DPresultdist2C);//total move to consensus with DP over all simulations (previous amount + the move in this round of simulation)

				
	//------------check for consensus-----------------------------------------------------
				if(p.checkconsensus(DelibResultsDP))
				{
					DPconsensuscounter=DPconsensuscounter+1;
				}
				if(p.checkconsensus(DelibResultsKS))
				{
					KSconsensuscounter=KSconsensuscounter+1;
				}
				if(p.checkconsensus(DelibResultsCS))
				{
					CSconsensuscounter=CSconsensuscounter+1;
				}
	
	//---------check for single peakedness--------------------------------------------
	
				for(int ref=0; ref< 13; ref++)
				{
					//deliberation DP
					if(DPcheck && PrefAgg.Rankings[ref].size()== 3)
					{
						if(p.singlePeakedProfile(DelibResultsDP, ref) || p.checkconsensus(DelibResultsDP))
						{
							DPsinglePeakedResultCounter= DPsinglePeakedResultCounter+1;
							if(p.checkforCycles(votes))
							{
								DPcycendSP=DPcycendSP+1; //counting cyclic profiles that end up single peaked with DP deliberation
							}			
							if(p.checkforNtran(votes))
							{
								DPNtranendSP=DPNtranendSP+1; //counting non-transitive profiles that end up single peaked with DP deliberation
							}			
							DPcheck=false;
						}
					}
					//deliberation with KS
					if(KScheck && PrefAgg.Rankings[ref].size()== 3)
					{
						if(p.singlePeakedProfile(DelibResultsKS, ref) || p.checkconsensus(DelibResultsKS))
						{
							KSsinglePeakedResultCounter= KSsinglePeakedResultCounter+1;
							if(p.checkforCycles(votes))
							{
								KScycendSP=KScycendSP+1; //counting cyclic profiles that end up single peaked with KS deliberation
							}
							if(p.checkforNtran(votes))
							{
								KSNtranendSP=KSNtranendSP+1; //counting non-transitive profiles that end up single peaked with KS deliberation
							}	
							KScheck=false;
						}
					}
					//CS deliberation
					if(CScheck && PrefAgg.Rankings[ref].size()== 3)
					{
						if(p.singlePeakedProfile(DelibResultsCS, ref) || p.checkconsensus(DelibResultsCS))
						{
							CSsinglePeakedResultCounter= CSsinglePeakedResultCounter+1;
							if(p.checkforCycles(votes))
							{
								CScycendSP=CScycendSP+1; //counting cyclic profiles that end up single peaked with CS deliberation
							}
							if(p.checkforNtran(votes))
							{
								CSNtranendSP=CSNtranendSP+1; //counting non-transitive profiles that end up single peaked with CS deliberation
							}	
							CScheck=false;
						}
					}
				}
	//--------------------check for weak single peakedness--------------------------------------------
				for(int ref=0; ref< 13; ref++)
				{
					//deliberation with DP
					if(DPwcheck && PrefAgg.Rankings[ref].size()== 3)
					{
						if(p.WsinglePeakedProfile(DelibResultsDP, ref))
						{
							DPwsinglePeakedResultCounter= DPwsinglePeakedResultCounter+1;
							if(p.checkforCycles(votes))
							{
								DPcycendwSP=DPcycendwSP+1; //counting cyclic profiles that end up weak single peaked with DP deliberation
							}
							if(p.checkforNtran(votes))
							{
								DPNtranendWSP=DPNtranendWSP+1;	//counting non-transitive profiles that end up weak single peaked with DP deliberation		
								
							}	
							DPwcheck=false;
						}
					}
					//deliberation with KS
					if(KSwcheck && PrefAgg.Rankings[ref].size()== 3)
					{
						if(p.WsinglePeakedProfile(DelibResultsKS, ref))
						{
							KSwsinglePeakedResultCounter= KSwsinglePeakedResultCounter+1;
							if(p.checkforCycles(votes))
							{
								KScycendwSP=KScycendwSP+1; //counting cyclic profiles that end up weak single peaked with KS deliberation
							}
							if(p.checkforNtran(votes))
							{
								KSNtranendWSP=KSNtranendWSP+1;	//counting non-transitive profiles that end up weak single peaked with KS deliberation		
								
							}	
							KSwcheck=false;
						}
					}
					//deliberation with CS
					if(CSwcheck && PrefAgg.Rankings[ref].size()== 3)
					{
						if(p.WsinglePeakedProfile(DelibResultsCS, ref))
						{
							CSwsinglePeakedResultCounter= CSwsinglePeakedResultCounter+1;
							if(p.checkforCycles(votes))
							{
								CScycendwSP=CScycendwSP+1; //counting cyclic profiles that end up weak single peaked with CS deliberation
							}
							if(p.checkforNtran(votes))
							{
								CSNtranendWSP=CSNtranendWSP+1;	//counting non-transitive profiles that end up weak single peaked with CS deliberation	
								
							}	
							CSwcheck=false;
						}
					}
				}
	//---------------check for single plateau--------------------------------------------
				for(int ref=0; ref< 13; ref++)
				{
					//deliberation with DP
					if(DPpcheck && PrefAgg.Rankings[ref].size()== 3)
					{
						if(p.SinglePlateauProfile(DelibResultsDP, ref))
						{
							DPSinglePlateau= DPSinglePlateau+1;
							
							if(p.checkforCycles(votes))
							{
								DPcycendSPla=DPcycendSPla+1;	//counting cyclic profiles that end up single plateau with DP deliberation							
							}		
												
							if(p.checkforNtran(votes))
							{
								DPNtranendSPla=DPNtranendSPla+1;	 //counting non-transitive profiles that end up single plateau with DP deliberation													
						
							}															
							DPpcheck=false;
						}
					}
					//deliberation with KS
					if(KSpcheck && PrefAgg.Rankings[ref].size()== 3)
					{
						if(p.SinglePlateauProfile(DelibResultsKS, ref))
						{
							KSSinglePlateau= KSSinglePlateau+1;
							
							if(p.checkforCycles(votes))
							{
								KScycendSPla=KScycendSPla+1;	 //counting cyclic profiles that end up single plateau with KS deliberation														
							}							
							if(p.checkforNtran(votes))
							{
								KSNtranendSPla=KSNtranendSPla+1; //counting cyclic profiles that end up single plateau with KS deliberation							
							}	
							KSpcheck=false;
						}
					}
					//deliberation with CS
					if(CSpcheck && PrefAgg.Rankings[ref].size()== 3)
					{
						if(p.SinglePlateauProfile(DelibResultsCS, ref))
						{
							CSSinglePlateau= CSSinglePlateau+1;
							
							if(p.checkforCycles(votes))
							{
								CScycendSPla=CScycendSPla+1;		//counting cyclic profiles that end up single plateau with CS deliberation												
							}							
							if(p.checkforNtran(votes))
							{
								CSNtranendSPla=CSNtranendSPla+1;	//counting non-transitive profiles that end up single plateau with DP deliberation							
							}	
							CSpcheck=false;
						}
					}
				}
	num=num+initNonTransitive; //number of non-transitive initial profiles over all simulations
			}
	//----------------calculating the averages and printing the results--------------
			CSmeandiffdist2C= (CSdiffdist2C/numSimulations); //average move to consensus
			KSmeandiffdist2C= (KSdiffdist2C/numSimulations);
			DPmeandiffdist2C= (DPdiffdist2C/numSimulations);
			
			DPavgclusters= ((double)DPclusters)/numSimulations; // average number of clusters
			KSavgclusters= ((double)KSclusters)/numSimulations;
			CSavgclusters= ((double)CSclusters)/numSimulations;
			
			cycremainingCS= (CScyc/cyc); //proportion of cycles remaining
			cycremainingDP= (DPcyc/cyc);
			cycremainingKS= (KScyc/cyc);
			if(ProximityCalc)
			{
				iniProx=((double)iniProximitytoSP)/numSimulations; //average proximity to single-plateauness initial votes
				iniStProx=((double)iniProximitytoSPeak)/numSimulations; //average proximity to single-peakedness initial votes
				KSProx=((double)KSProximitytoSP)/numSimulations;  //average proximity to single-plateauness after KS deliberation
				DPProx=((double)DPProximitytoSP)/numSimulations;   //average proximity to single-plateauness after DP deliberation
				CSProx=((double)CSProximitytoSP)/numSimulations;   //average proximity to single-plateauness after CS deliberation
				KSStProx=((double)KSProximitytoSPeak)/numSimulations; //average proximity to single-peakedness after KS deliberation
				DPStProx=((double)DPProximitytoSPeak)/numSimulations; //average proximity to single-peakedness after DP deliberation
				CSStProx=((double)CSProximitytoSPeak)/numSimulations;	//average proximity to single-peakedness after CS deliberation		
						
			}
			
			
			double DPNontranEndSinglePlateau;
			double KSNontranEndSinglePlateau;
			double CSNontranEndSinglePlateau;
			
			DPNontranEndSinglePlateau=((double)DPNtranendSPla)/initNonTransitive; //proportion of initially non-transitive profiles that end up single plateau with DP deliberation
			KSNontranEndSinglePlateau=((double)KSNtranendSPla)/initNonTransitive;//proportion of initially non-transitive profiles that end up single plateau with KS deliberation
			CSNontranEndSinglePlateau=((double)CSNtranendSPla)/initNonTransitive;	//proportion of initially non-transitive profiles that end up single plateau with CS deliberation

			try
			{
				FileWriter fw = new FileWriter(outputfile,true);
				BufferedWriter bw = new BufferedWriter(fw);
				PrintWriter pw = new PrintWriter(bw);
				if(ProximityCalc)
				{
					pw.println(q+","+rel+","+cyc+","+initNonTransitive+","+iniStProx+","+iniProx+","+DPcyc+","+cycremainingDP+","+DPmeandiffdist2C+","+DPavgclusters+","+DPNtran+","+DPStProx+ ","+DPProx+","+DPNontranEndSinglePlateau+","+KScyc+","+cycremainingKS+","+KSmeandiffdist2C+","+KSavgclusters+","+KSNtran+","+KSStProx+ "," +KSProx+","+KSNontranEndSinglePlateau+","+CScyc+","+cycremainingCS+","+CSmeandiffdist2C+","+CSavgclusters+","+CSNtran+","+CSStProx+ "," +CSProx+","+CSNontranEndSinglePlateau);
				}
				
				pw.flush();
				pw.close();
				//JOptionPane.showMessageDialog(null,"Data Saved");
			}
			catch(Exception E)
			{
				JOptionPane.showMessageDialog(null,"Data NOT Saved1");
			}
		}
	System.out.println("--------------------------------");
	System.out.println("--------------------------------");
	System.out.println("--------------------------------");
	System.out.println("--------------------------------");
	}
}	
}
